<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="initial-scale=1.0, user-scalable=no, width=device-width"
    />
    <title>登封热力供暖地图</title>
    <link rel="stylesheet" href="./main.css?v=6" />
    <link rel="stylesheet" href="./bootstrap.min.css" />
    <link rel="stylesheet" href="./bootstrap.icon.css" />
    <script src="./vue.js"></script>
    <script>
      const { createApp, ref, computed } = Vue;
      function initVueApp() {
        createApp({
          setup() {
            const message = ref("Hello vue!");
            const searchArea = ref("");
            const mapToArea = (item) => {
              map.setZoomAndCenter(20, item.lnglat, true);
              infoWindow.setContent(createInfoWindow(item));
              infoWindow.open(map, item.lnglat);
            };
            const list = ref(locationList);
            const filterLocationList = computed(() => {
              return list.value.filter((t) =>
                t.properties.name.includes(searchArea.value)
              );
            });
            return {
              message,
              filterLocationList,
              mapToArea,
              searchArea,
            };
          },
        }).mount("#app");
      }
    </script>
  </head>
  <body>
    <div id="app">
      <a
        class="btn btn-primary"
        data-bs-toggle="offcanvas"
        href="#offcanvasExample"
        role="button"
        aria-controls="offcanvasExample"
        @click="showCanvas=!showCanvas"
      >
        查看所有小区
      </a>

      <div
        class="offcanvas offcanvas-end"
        tabindex="-1"
        id="offcanvasExample"
        data-bs-backdrop="false"
        aria-labelledby="offcanvasExampleLabel"
      >
        <div class="offcanvas-header">
          <h5 class="offcanvas-title" id="offcanvasExampleLabel">小区列表</h5>
          <button
            type="button"
            class="btn-close"
            data-bs-dismiss="offcanvas"
            aria-label="Close"
          ></button>
        </div>
        <div class="offcanvas-body">
          <div class="input-group mb-3 d-flex align-items-stretch">
            <span class="input-group-text" id="basic-addon1">
              <i class="bi bi-search"></i>
            </span>
            <input
              type="text"
              class="form-control"
              placeholder="搜索小区名字"
              aria-label="搜索小区名字"
              aria-describedby="basic-addon2"
              v-model="searchArea"
            />
            <button
              type="button"
              class="btn btn-outline-danger clear-btn"
              @click="searchArea=''"
              :class="{ 'd-none': searchArea === '' }"
            >
              <i class="bi bi-x-circle"></i>
            </button>
          </div>
          <ul class="list-group">
            <a
              v-for="item in filterLocationList"
              :key="item.id"
              class="list-group-item list-group-item-action"
              @click="mapToArea(item)"
            >
              {{item.properties.name}}
            </a>
          </ul>
          <div class="card" v-if="filterLocationList.length==0">
            <div class="card-body">无匹配内容</div>
          </div>
        </div>
      </div>
    </div>
    <div id="container"></div>
    <div class="info">
      <span>登封市区当前接入供暖小区共计: <b id="totalCount"></b></span>
      <button onClick="returnToInit()" title="回到地图中心">
        <img width="32" src="./home.png" />
      </button>
    </div>
    <script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=2.0&key=1d5604d03e8dbb2ce554f432b54509d3&plugin=AMap.MarkerCluster"
    ></script>
    <script type="text/javascript">
      function isMobile() {
        const userAgentInfo = navigator.userAgent;
        const mobileAgents = [
          "Android",
          "iPhone",
          "SymbianOS",
          "Windows Phone",
          "iPad",
          "iPod",
        ];
        const mobileFlag = mobileAgents.some((mobileAgent) => {
          return userAgentInfo.indexOf(mobileAgent) > 0;
        });

        return mobileFlag;
      }
      var isPc = !isMobile();
      //地图初始化时，在地图上添加一个marker标记,鼠标点击marker可弹出自定义的信息窗体
      var initCenter = [113.0562, 34.452794];
      var initZoom = window.innerWidth < 768 ? 12 : 14;
      var map = new AMap.Map("container", {
        resizeEnable: true,
        center: initCenter, // 中心点东转盘
        zoom: initZoom, // 缩放登记，值越大，视野越小，可调 2 ~ 22
      });

      const returnToInit = () => {
        map.setZoomAndCenter(initZoom, initCenter);
      };

      var markerOverlayList = [];
      var locationList = [];
      let cluster;
      const gridSize = 60;
      var markerCount;
      // 加载数据
      fetch("./data.json")
        .then((t) => t.json())
        .then((res) => {
          console.log(res);
          locationList = res.features.map((t, i) => {
            markerOverlayList.push({
              marker: new AMap.Marker({
                position: t.geometry.coordinates,
                opacity: 0,
              }),
              id: i,
            });
            return {
              properties: t.properties,
              lnglat: t.geometry.coordinates,
              id: i,
            };
          });
          initVueApp();
          // 数据中需包含经纬度信息字段 lnglat
          // var points = [
          // { lnglat: ["108.939621", "34.343147"] },
          // { lnglat: ["112.985037", "23.15046"] },
          // ...
          // ...
          // ]
          markerCount = locationList.length;
          document.querySelector("#totalCount").innerHTML = markerCount;
          // 1=六边形 0=高光
          addCluster(2, locationList);
          //添加聚合点点击事件
          cluster.on("click", (data) => {
            //判断是否是聚合点，不是聚合点就执行单个点击方式
            if (data.clusterData.length <= 1) return;
            const filterList = markerOverlayList.filter((p) =>
              data.clusterData.some((t) => t.id === p.id)
            );

            setTimeout(() => {
              map.setFitView(filterList.map((t) => t.marker));
            });
          });
        });

      var _renderClusterMarker = function (context) {
        var factor = Math.pow(context.count / markerCount, 1 / 18);
        var div = document.createElement("div");
        var Hue = 180 - factor * 180;
        var bgColor = "hsla(" + Hue + ",100%,40%,0.7)";
        var fontColor = "hsla(" + Hue + ",100%,90%,1)";
        var borderColor = "hsla(" + Hue + ",100%,40%,1)";
        var shadowColor = "hsla(" + Hue + ",100%,90%,1)";
        div.style.backgroundColor = bgColor;
        var size = Math.round(
          30 + Math.pow(context.count / markerCount, 1 / 5) * 20
        );
        div.style.width = div.style.height = size + "px";
        div.style.border = "solid 1px " + borderColor;
        div.style.borderRadius = size / 2 + "px";
        div.style.boxShadow = "0 0 5px " + shadowColor;
        div.innerHTML = context.count;
        div.style.lineHeight = size + "px";
        div.style.color = fontColor;
        div.style.fontSize = "14px";
        div.style.textAlign = "center";
        context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
        context.marker.setContent(div);

        //添加鼠标移入放大效果
        // cluster.marker.on("mouseover", () => {
        //   cluster.marker.setIcon(
        //     new AMap.Icon({
        //       image: cluster.marker.getIcon()._opts.image,
        //       size: new AMap.Size(40, 50), //根据image分辨率计算放大后尺寸
        //       imageSize: new AMap.Size(40, 50),
        //     })
        //   );
        //   cluster.marker.setLabel({
        //     content: `<span style="cursor: pointer;font-size: 20px;">${cluster.count}</span>`,
        //     direction: "center",
        //     offset: new AMap.Pixel(0, -5),
        //   });
        // });
        // //鼠标移出还原
        // cluster.marker.on("mouseout", () => {
        //   cluster.marker.setIcon(
        //     new AMap.Icon({
        //       image: cluster.marker.getIcon()._opts.image,
        //       size: new AMap.Size(32, 40),
        //       imageSize: new AMap.Size(32, 40),
        //     })
        //   );
        //   cluster.marker.setLabel({
        //     content: `<span style="cursor: pointer;">${cluster.count}</span>`,
        //     direction: "center",
        //     offset: new AMap.Pixel(0, -5),
        //   });
        // });
      };
      // 供暖点大小
      var size = [30, (70 / 51) * 30];
      const icon = new AMap.Icon({
        image:
          "https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png",
        size: size,
        imageSize: size,
      });
      var _renderMarker = function (context) {
        var offset = new AMap.Pixel(-9, -9);
        // context.marker.setContent(content);
        context.marker.setTitle(context.data[0].properties.name);
        context.marker.setOffset(offset);
        context.marker.setIcon(icon);
        context.marker.on("click", () => {
          const params = context.data[0];
          //鼠标点击marker弹出自定义的信息窗体
          infoWindow.setContent(createInfoWindow(params));
          infoWindow.open(map, context.marker.getPosition());
        });
      };

      function addCluster(tag, points) {
        if (cluster) {
          cluster.setMap(null);
        }
        if (tag == 2) {
          //完全自定义
          cluster = new AMap.MarkerCluster(map, points, {
            gridSize: gridSize, // 设置网格像素大小
            renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式
            renderMarker: _renderMarker, // 自定义非聚合点样式
          });
        } else if (tag == 1) {
          //自定义图标
          var sts = [
            {
              url: "//a.amap.com/jsapi_demos/static/images/blue.png",
              size: new AMap.Size(32, 32),
              offset: new AMap.Pixel(-16, -16),
            },
            {
              url: "//a.amap.com/jsapi_demos/static/images/green.png",
              size: new AMap.Size(32, 32),
              offset: new AMap.Pixel(-16, -16),
            },
            {
              url: "//a.amap.com/jsapi_demos/static/images/orange.png",
              size: new AMap.Size(36, 36),
              offset: new AMap.Pixel(-18, -18),
            },
            {
              url: "//a.amap.com/jsapi_demos/static/images/red.png",
              size: new AMap.Size(48, 48),
              offset: new AMap.Pixel(-24, -24),
            },
            {
              url: "//a.amap.com/jsapi_demos/static/images/darkRed.png",
              size: new AMap.Size(48, 48),
              offset: new AMap.Pixel(-24, -24),
            },
          ];
          cluster = new AMap.MarkerCluster(map, points, {
            styles: sts,
            gridSize: gridSize,
          });
        } else {
          //默认样式
          cluster = new AMap.MarkerCluster(map, points, { gridSize: gridSize });
        }
      }

      var infoWindow = new AMap.InfoWindow({
        isCustom: true, //使用自定义窗体
        content: "",
        offset: new AMap.Pixel(16, -45),
      });
      //构建自定义信息窗体
      function createInfoWindow(params) {
        var title = params.properties.name;
        var detail = params.properties.tips;
        var content = [];
        // 浩看---不需要图片展示可以屏蔽，图片只是为了展示能力，目前还未接入可能需要图床服务才行
        content.push(
          "<img src='http://tpc.googlesyndication.com/simgad/5843493769827749134'>"
        );
        content.push(detail);
        var info = document.createElement("div");
        info.className = "custom-info input-card content-window-card";

        //可以通过下面的方式修改自定义窗体的宽高
        info.style.width = "400px";
        // 定义顶部标题
        var top = document.createElement("div");
        var titleD = document.createElement("div");
        var closeX = document.createElement("img");
        top.className = "info-top";
        titleD.innerHTML = title;
        closeX.src = "https://webapi.amap.com/images/close2.gif";
        closeX.onclick = closeInfoWindow;

        top.appendChild(titleD);
        top.appendChild(closeX);
        info.appendChild(top);

        // 定义中部内容
        var middle = document.createElement("div");
        middle.className = "info-middle";
        middle.style.backgroundColor = "white";
        middle.innerHTML = content;
        info.appendChild(middle);

        // 定义底部内容
        var bottom = document.createElement("div");
        bottom.className = "info-bottom";
        bottom.style.position = "relative";
        bottom.style.top = "0px";
        bottom.style.margin = "0 auto";
        var sharp = document.createElement("img");

        sharp.src = "https://webapi.amap.com/images/sharp.png";
        bottom.appendChild(sharp);
        info.appendChild(bottom);
        return info;
      }

      //关闭信息窗体
      function closeInfoWindow() {
        map.clearInfoWindow();
      }
    </script>
    <script src="./bootstrap.min.js"></script>
  </body>
</html>
